package org.genuflex.utils
{
	import mx.collections.ArrayCollection;
	
	public class GenuflexHierarchyDataHelper
	{
		
		/*
		 * sortIntoTree
		 *
		 * Takes an array collection of objects and re-organizese them into a tree
		 *  structure using the same assumption that mx:Tree does... that an ArrayCollection
		 *  called 'children' exists to maintain the structure
		 */
		 public static function sortIntoTree(objectArray : ArrayCollection, 											
											parentKey : String, 
											childKey : String               ) : ArrayCollection {
												
			var objectTree : ArrayCollection  = new ArrayCollection();
			var object : Object = null;
			var parentObject : Object = null;			
			
			if (objectArray != null && objectArray.length > 0) {
			
				//Now, run through the objects to build the tree
				for(var i:int=0; i < objectArray.length; i++) {
					object = objectArray[i];
					
					parentObject = findParent(object[parentKey], childKey, objectArray);
					
					//This object's parent has been loaded
					if (parentObject != null) {
						if (parentObject.children == null) {
							parentObject.children = new ArrayCollection();
						}
						
						parentObject.children.addItem(object);
					}
					//No parent has been loaded
					else {
						objectTree.addItem(object);
					}							
				}
			}
			
			return objectTree;	
		}
		
		/*
		 * placeIntoTree
		 *
		 * Takes an array of objects that belong in an existing tree. It will
		 *  iterate through the objects finding their respective parents and
		 *  place them accordingly
		 */
		public static function placeIntoTree(children : ArrayCollection,
											 parentTree : ArrayCollection,
											 parentKey : String, 
											 childKey : String               ) : ArrayCollection {
												
			var child : Object = null;
			var parentObject : Object = null;			
			
			if (children != null && parentTree != null && children.length > 0) {
			
				//Now, run through the objects to populate the tree			
				for(var i:int=0; i < children.length; i++) {
					child = children[i];
					
					if (child[parentKey] > 0) {
						parentObject = findInTree(parentTree, childKey, child[parentKey]);
					}
					else {
						parentObject = null;
					}
					
					//This object's parent has been loaded
					if (parentObject != null) {
						if (parentObject.children == null) {
							parentObject.children = new ArrayCollection();
						}
						
						parentObject.children.addItem(child);
					}
				}		
			}
			
			return parentTree;	
		}		
		
		private static function findParent(parentID : int, childKey : String, parentArray : ArrayCollection) : Object {
			for(var i:int=0; i < parentArray.length; i++) {
				if (parentArray[i][childKey] == parentID) {
					return parentArray[i];
				}
			}
			
			//Not found
			return null;
		}	
		
		public static function findInTree(objectTree : Object, foreignKey : String, id : int) : Object {
			if (objectTree != null) {
								
				var target : Object = null;
				
				//Iterate through the top-levels of the ArrayCollection
				// and keep digging if you have to
				if (objectTree is ArrayCollection) {
					for(var i:int=0; i < objectTree.length; i++) {

						//A parent object must have a children property
						if (objectTree[i].hasOwnProperty("children")) {
							if (objectTree[i][foreignKey] == id) {
								target = objectTree[i];
							}
							else if (objectTree[i].children != null) {
								target = findInTree(objectTree[i].children, foreignKey, id);									
							}
							
							//Did we find something?
							if (target != null) {
								return target;
							}
							
						}
					}
				}
				//A single object was passed in and it matches
				else if (objectTree[foreignKey] == id) {						
					return objectTree;
				}																			
			}
			
			return null;
		}	
	}
}